package com.moli.iov.sys.remote.impl;

import com.moli.iov.exception.BusinessException;
import com.moli.iov.rest.RestResponse;
import com.moli.iov.sys.component.CredentialsMatcher;
import com.moli.iov.sys.component.TokenUtils;
import com.moli.iov.sys.enums.CompanyStatusEnum;
import com.moli.iov.sys.enums.SuperAdminEnum;
import com.moli.iov.sys.enums.UserStatusEnum;
import com.moli.iov.sys.enums.UserTypeEnum;
import com.moli.iov.sys.model.dto.req.AuthenticationDto;
import com.moli.iov.sys.model.dto.res.LoginDto;
import com.moli.iov.sys.model.po.Company;
import com.moli.iov.sys.model.po.Permission;
import com.moli.iov.sys.model.po.User;
import com.moli.iov.sys.remote.IAuthenticationRemoteService;
import com.moli.iov.sys.remote.IPermissionRemoteService;
import com.moli.iov.sys.remote.IUserRemoteService;
import com.moli.iov.sys.service.ICompanyService;
import com.moli.iov.sys.service.IPermissionService;
import com.moli.iov.sys.utils.PwdUtil;
import com.moli.iov.util.ValidationUtils;
import java.util.ArrayList;
import java.util.List;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;

/**
 * <p>
 * 身份认证
 * </p>
 *
 * @author zql
 * @since 2019/9/26 12:40
 */
@Slf4j
@Service(group = "${service.group}")
public class AuthenticationRemoteServiceImpl implements IAuthenticationRemoteService {

  @Autowired
  private IUserRemoteService userRemoteService;

  @Autowired
  private IPermissionRemoteService permissionRemoteService;

  @Autowired
  private IPermissionService permissionService;

  @Autowired
  private TokenUtils tokenUtils;

  @Autowired
  private CredentialsMatcher credentialsMatcher;

  @Autowired
  private ICompanyService companyService;

  @Value("${pwd.prefix}")
  private String pwdPrefix;

  /**
   * 登陆
   * @param authenticationDto
   * @return
   */
  @Override
  public RestResponse<LoginDto> login(AuthenticationDto authenticationDto) {
    User user = loginValid(authenticationDto);

    List<Permission> permissions = new ArrayList<>();
    List<Permission> apiPermissions = new ArrayList<>();
    //超级管理员
    if(user.getIsSuperAdmin() != null && SuperAdminEnum.YES.getFlag() == user.getIsSuperAdmin()){
      permissions = permissionRemoteService.listTreePermissionOfSuperAdmin(user.getUserType());
      apiPermissions = permissionService.listApiAndBtnPermissionsOfAll();

    }else{
      permissions = permissionRemoteService.listTreePermission(user.getUserId());
      apiPermissions = permissionRemoteService.listApiAndBtnPermission(user.getUserId());
    }

    LoginDto loginDto = new LoginDto(
        user, permissions, apiPermissions, tokenUtils.generateTokenAndHead(user.getAccount()));
    return RestResponse.success(loginDto);
  }

  /**
   * 登录校验
   * @param authenticationDto
   * @return
   */
  private User loginValid(AuthenticationDto authenticationDto){

    ValidationUtils.restResponseValidate(authenticationDto, AuthenticationDto.Login.class);


    RestResponse<User> response = userRemoteService
        .getUserByAccount(authenticationDto.getAccount());
    if(!response.flag){
      throw new BusinessException(response.getMessage());
    }

    User user = response.getData();

    if(authenticationDto.getPassword().length() <= pwdPrefix.length()) {
      throw new BusinessException("密码错误");
    }

    String pwd = PwdUtil.decodePwd(pwdPrefix, authenticationDto.getPassword());
    if(!credentialsMatcher.doCredentialsMatch(pwd, user.getPassword())){
      throw new BusinessException("密码错误");
    }

    if(UserStatusEnum.ENABLED.getFlag() != user.getStatus()){
      throw new BusinessException("用户已停用");
    }

    if(UserTypeEnum.COMPANY.getFlag() == user.getUserType()){
      if(user.getCompanyId() == null){
        throw new BusinessException("缺少企业信息");
      }
      Company company = companyService.getById(user.getCompanyId());
      if(company == null){
        throw new BusinessException("企业信息异常");
      }

      if(CompanyStatusEnum.ENABLED.getFlag() != company.getStatus()){
        throw new BusinessException("企业已停用");
      }
    }

    return user;
  }

}
